(function(H, undefined){
	var mDlg,
	singleSUCount = 0,
	// 调用com组件的配置
	comConfig = null,
	count = 0,
	// 获取要传给flash的post参数
	getPostParams = function(rules) {
		var params = H.page.getParams();
		H.extend(params, {jhu: H.page.getCookie('jhu') || '', jid:H.page.getCookie('jid') || '' ,jwidth:H.page.getCookie('jwidth') || ''});
		if (rules) {
			if (H.isArray(rules)) {
				rules = rules.join(',');
			}
			H.extend(params, {'rules': rules});
		}
		//速度的上限和下限
		H.extend(params, {'maxSpace':100});
		H.extend(params, {'minSpace':20});
		return params;
	},
	me = {
		init: function(cfg){
			comConfig = cfg;
		},
		active:function(id, rules, type, watermark, vars,uid) {
			if (undefined === type || false === type) {
				type = 'single';
			} else if(true === type) {
				type = 'multi';
			}
			watermark = !!watermark;
			
			switch(type) {
				case 'single':
					var params = getPostParams(rules);
					if (watermark) {
						params.watermark = 1;
					}
					var cfg = H.extend({
						'button_placeholder_id': id,
						'post_params': params
					}, comConfig);
					return this.directUpload(cfg, true);
				case 'dmulti':
					var params = getPostParams(rules);
					if (watermark) {
						params.watermark = 1;
					}
					var cfg = H.extend({
						'button_placeholder_id': id,
						'post_params': params
					}, comConfig);
					return this.directUpload(cfg, false);
				case 'multi':
					if (H.isArray(rules)) {
						rules = rules.join(',');
					}
					
					var params = {
						rules:rules // 设置图片规格
					};
					if (watermark) {
						params.watermark = 1;
					}
					H.ui.on(H.ui._id(id), 'click', function(){
						me.uploadMulti(params);
						return false;
					});
					return {
						setCallback:this.setMultiCallback
					};
					break;
				case 'mupload':
					var ps = getPostParams(rules);
					if (watermark) {
						ps.watermark = 1;
					}
					var flashvars = {
						callback: 'onUploadComplete',
						params: encodeURIComponent(H.lib.serial.toString(ps, 'json')),
						url: comConfig.upload_url,
						filename: comConfig.file_post_name || 'upload',
						rate: comConfig.rate || 1
					};
					var swfVersionStr = "10.0.0";
		            var xiSwfUrlStr = 'playerProductInstall.swf';
		            var params = {};
		          	params.quality = 'high';
		            params.wmode = 'transparent';
		            params.bgcolor = '#ffffff';
		            params.allowfullscreen = 'true';
		            params.allowscriptaccess = 'always';
		            var attributes = {};
		            attributes.id = 'mupload';
		            attributes.name = 'mupload';
		            swfobject.embedSWF(
		                comConfig.multi_url, id, 
						comConfig.multi_width,
						comConfig.multi_height,
		                swfVersionStr, xiSwfUrlStr, 
		                flashvars, params, attributes);
									
					return {
						setCallback: function(callback) {
							var arrData=[];
							window.onUploadComplete = function(ret,num,total) {
								var ret = H.lib.serial.getJson(ret);
								if (ret.err.indexOf('ok') > -1) {
									arrData.push(ret.data);
								} else {
									H.ui.dialog.error(ret.err);
								}
								if(num === total){
									callback.call(null, arrData);
								}
							};
						}
					};
					break;
				case 'crop':
					var ps = getPostParams(rules),
					flashvars = {
						callback: 'onUploadComplete',
						params: encodeURIComponent(H.lib.serial.toString(ps, 'json')),
						url: comConfig.upload_url,
						filename: comConfig.file_post_name || 'upload',
						rate: comConfig.rate || 1
					}
					;
					if (vars) {
						H.extend(flashvars, vars);
					}
					var swfVersionStr = "10.0.0";
		            var xiSwfUrlStr = 'playerProductInstall.swf';
		            var params = {};
		            params.quality = 'high';
		            params.wmode = 'transparent';
		            params.bgcolor = '#ffffff';
		            params.allowfullscreen = 'true';
		            params.allowscriptaccess = 'always';
		            var attributes = {};
		            attributes.id = 'PicUpload';
		            attributes.name = 'PicUpload';
		            attributes.align = 'middle';
		            swfobject.embedSWF(
		                comConfig.crop_url, id, 
		                '100%', 
						'100%', 
		                swfVersionStr, xiSwfUrlStr, 
		                flashvars, params, attributes);
									
					return {
						setCallback: function(callback) {
							window.onUploadComplete = function(ret) {
								var ret = H.lib.serial.getJson(ret);
								if (!ret.err || ret.err.indexOf('ok') > -1) {
									callback.call(null, ret.data);
								} else {
									H.ui.dialog.error(ret.err);
								}
							};
						}
					};
					break;
				case 'muploader':
					var ps = getPostParams(rules),uid = (undefined !== uid)? uid : null;
					//console.log(ps);
					//console.log(uid);
					//console.log(vars);
					if(!vars){
						vars = {};
						var st = eval('('+H.ui._id(id).getAttribute('st')+')');
						if(attrstyle(H.ui._id(id),'color')){
							vars.color = rgb2hex(attrstyle(H.ui._id(id),'color')).replace('#','');
						}else{
							vars.color = rgb2hex('#000000').replace('#','');
						}
						var bg = rgb2hex(attrstyle(H.ui._id(id),'backgroundColor'));
						if(bg.charAt(0) == "#"){
							vars.bgcolor = bg.replace(/#/,'');
						}else if(st.bgcolor){
							vars.bgcolor = st.bgcolor.replace(/#/,'');
						}else{
							vars.bgcolor = "ffffff";
						}
						vars.w = (attrstyle(H.ui._id(id),'width')) ? attrstyle(H.ui._id(id),'width').replace('px','') : st.w;
						vars.h = (attrstyle(H.ui._id(id),'height')) ? attrstyle(H.ui._id(id),'height').replace('px','') : st.h;
						vars.txt = H.ui._id(id).innerHTML;
					}
					
					if (watermark) {
						ps.watermark = 1;
					}
					if(uid == 'editor'){
						uid = 'editor'+count;
					}
					count++;
					var f = checkflashplayer();
					if(f.substr(0,2)>9){
						var flashvars = {
							uid: uid,
							params: encodeURIComponent(H.lib.serial.toString(ps, 'json')),
							url: encodeURIComponent(comConfig.upload_url),
							filename: comConfig.file_post_name || 'upload',
							rate: comConfig.rate || 1,
							style:encodeURIComponent(H.lib.serial.toString(vars, 'json')),
							testurl:'http://' + hapj.staticHost + '/util/image/img/test.jpg'
						};
						var swfVersionStr = "10.0.0";
			            var xiSwfUrlStr = 'playerProductInstall.swf';
			            var params = {};
			          	params.quality = 'high';
			            params.wmode = 'transparent';
			            params.bgcolor = '#ffffff';
			            params.allowfullscreen = 'true';
			            params.allowscriptaccess = 'always';
			            var attributes = {};
			            attributes.id = uid;
			            attributes.name = uid;
			            swfobject.embedSWF(
			                comConfig.multi_url, id, 
							(vars.w)? vars.w:comConfig.muploader_width,
							(vars.h)? vars.h:comConfig.muploader_height,
			                swfVersionStr, xiSwfUrlStr, 
			                flashvars, params, attributes);
						return {
							setCallback: function(callback,loadcallback,selectcallback) {
								uploader.id[uid] = {};
								uploader.id[uid][0]=callback;
								if(loadcallback){
									uploader.id[uid][1]=loadcallback;	
								}
								if(selectcallback){
									uploader.id[uid][2]=selectcallback;	
								}
							}
						}
					}else{
						normalupload(vars,uid,id,comConfig,ps.rules,watermark)
						return{
							setCallback: function(callback){
								H.ui.id('iframe_data'+uid).on('load',function(){
									var doc = this.contentWindow.document,
									html = doc.body.innerHTML;
									if(html!=''){
										var obj = eval('('+html+')');
										if(obj.err == 'hapn.ok'){
											callback(obj.data,'normal');
										}else{
											alert('上传失败');
										}
										
									}
								});
							}
						}			
					};
				case 'video':
					flashvars = {
							vinfo:vars.vinfo,
							videoUrl:vars.videoUrl,
							picUrl:vars.picUrl
						}
					var swfVersionStr = "10.0.0";
		            var xiSwfUrlStr = 'playerProductInstall.swf';
		            var params = {};
		            params.movie = 'HapPlayer.swf';
		            params.quality = 'high';
		            params.play = 'true';
		            params.loop = 'true';
		            params.wmode = 'window';
		            params.scale = 'showall';
		            params.menu = 'fales';
		            params.devicefont = 'false'; 
		            params.bgcolor = '#ffffff';
		            params.allowfullscreen = 'true';
		            params.allowscriptaccess = 'sameDomain';
		            var attributes = {};
		            attributes.id = 'playVideo';
		            attributes.name = 'playVideo';
		            attributes.align = 'middle';
		            swfobject.embedSWF(
		                comConfig.video_url, id, 
		                '100%', 
						'100%', 
		                swfVersionStr, xiSwfUrlStr, 
		                flashvars, params, attributes);	
			}	
		},
		/**
		 * 获取上传器
		 * 
		 * @param {Object}
		 *            cfg <code>{
		 * 	flashUrl: flash地址
		 *  uploadUrl: 上传地址
		 *  ext: 允许上传的文件。默认为(*.jpeg;*.jpe;*.gif;*.png)
		 *  btnId: 上传的按钮
		 *  btnBg: 上传按钮的背景
		 *  btnText: 上传按钮的文本，默认为添加文件
		 *  count: 上传文件的个数，默认为5
		 *  size：上传文件的最大尺寸，默认为 2MB
		 *  params：通过post提交到服务器端的数据。
		 * }</code>
		 */
		getUploader: function(cfg) {
			H.extend(cfg, {
				file_upload_limit: 20,
				// 事件处理
				file_queued_handler : fileQueued,// 添加成功
				file_queue_error_handler : fileQueueError,// 添加失败
				upload_start_handler : uploadStart,// 上传开始
				upload_progress_handler : uploadProgress,// 上传进度
				upload_error_handler : uploadError,// 上传失败
				upload_success_handler : uploadSuccess,// 上传成功
				upload_complete_handler : uploadComplete// 上传结束
			});
			
			return new SWFUpload(cfg);
		},
		/**
		 * 上传单个文件
		 */
		directUpload: function(cfg, single) {
			if (typeof single == 'undefined') {
				single = true;
			}
			H.extend(cfg, {
				button_action: single ? -100 : -110,
				file_upload_limit: 20,
				file_queue_limit: 0,
				
				// file_queued_handler : Handler.fileQueued,
				file_queue_error_handler: Handler.fileQueueError,
				file_dialog_complete_handler: Handler.fileDialogComplete,
				// upload_start_handler : Handler.uploadStart,
				// upload_progress_handler : Handler.uploadProgress,
				upload_error_handler: Handler.uploadError,
				// upload_success_handler: Handler.uploadSuccess,
				upload_success_handler: (function(index){
					return function(file, serverData) {
						try {
							var ret = H.lib.serial.getJson(serverData);
							if (!ret.err || ret.err.indexOf('ok') >= 0) {
								Handler.callback[index].call(this, ret.data);
							} else {
								Handler.alert(ret.err);
							}
						}catch(ex) {
							this.debug(ex);
						}
					}
				})(singleSUCount),
				upload_complete_handler: Handler.uploadComplete,
				queue_complete_handler: Handler.queueComplete
			});
			var ret = {
				swfuploader: new SWFUpload(cfg),
				index:singleSUCount,
				setCallback: function(callback) {
					Handler.callback[this.index] = function(){
						var args = [], id = cfg.button_placeholder_id;
						H.each(arguments, function(i){
							args.push(this);
						})
						args.push(id);
						callback.apply(H.ui._id(id), args);
					};
				}
			}
			singleSUCount++;
			return ret;
		},
		/**
		 * 上传多个文件
		 * 
		 * @param {Object}
		 *            params 要传入服务器端的变量
		 */
		uploadMulti: function(params) {
			params = params || {};
			mDlg = H.ui.dialog;
			var p = H.lib.serial.toString(params, 'pair');
			mDlg.size(710, 500)
			.iframe('/util/image/multi/?' + p)
			.title('上传文件');
		},
		/**
		 * 设置多传的回调函数
		 * 
		 * @param {Object}
		 *            callback
		 */
		setMultiCallback: function(callback) {
			window.onMultiUploaded = function(imgs){
				mDlg && mDlg.hide();
				H.each(imgs, function(){
					if (this.url && this.url[0] == '!') {
						this.url = this.url.substr(1);
					}
				});
				callback.call(null, imgs);
			}
		}
	};
	H.set('image', me);
	
	window.Handler = {
		callback:[],
		alert:function(str){
			H.ui.dialog.error(str);
		},
        fileDialogComplete: function(numFilesSelected, numFilesQueued){
            try {
                if (numFilesSelected > 20) {
                   	return Handler.alert('一次只能上传20张图片');
                }
                /* I want auto start the upload and I can do that here */
                this.startUpload();
            } 
            catch (ex) {
                this.debug(ex);
            }
        },
        uploadError: function(file, errorCode, message){
			try {
				switch (errorCode) {
				case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
					Handler.alert("上传错误: " + message);
					this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
					break;
				case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
					Handler.alert("上传失败.");
					this.debug("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
					break;
				case SWFUpload.UPLOAD_ERROR.IO_ERROR:
					Handler.alert("服务器错误.");
					this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
					break;
				case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
					Handler.alert("安全问题.");
					this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
					break;
				case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
					Handler.alert("超过上传限制.");
					this.debug("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
					break;
				case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
					Handler.alert("验证失败.");
					this.debug("Error Code: File Validation Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
					break;
				case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
					// progress.setStatus("Cancelled");
					// progress.setCancelled();
					break;
				case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
					// progress.setStatus("Stopped");
					break;
				default:
					// progress.setStatus("Unhandled Error: " + errorCode);
					Handler.alert('上传失败.');
					this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
					break;
				}
			} catch (ex) {
		        this.debug(ex);
		    }
        },
		uploadComplete:function(file){
        	if (this.getStats().files_queued !== 0) {
    			this.startUpload();
    		}
		},
		uploadSuccess:function(file, serverData) {
			try {
				if (typeof _successCallback == 'function') {
					_successCallback.call(this, serverData);
				}
			} catch (ex) {
				this.debug(ex);
			}
		},
		queueComplete:function(){
		},
        fileQueueError:function(file, errorCode, message){
            try {
                switch(errorCode) {
                    case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
                        Handler.alert('文件大小超过限制(最大' + comConfig['file_size_limit'] + ')');
                        break;
                }
            } catch (ex) {
                this.debug(ex);
            }
        }
	} 
})(hapj);

var uploaderinit = function(){
	var arrData=[],options = {},setcover = false;
	uploader = {
		init:function(o){
			options = o;
		},
		id:{}
	};
	uploader.fileSelected = function(data){
		uploader.id[data.uid][2].call(null, data);
	}
		// 加载图片
	uploader.loadComplete = function(data) {
		uploader.id[data.uid][1].call(null, data);
	}
	// 图片上传完毕
	uploader.uploadComplete = function(data) {
		var ret = eval('(' + data.ret + ')');
		switch(ret.err) {
			case 'hapn.u_notfound':
				return alert('上传地址不存在');
			case 'hapn.u_login':
				return alert('您尚未登录，不能上传');
			case 'hapn.u_power':
				return alert('您无权操作');
			case 'hapn.ok':
				break;
			default:
				return alert(ret.err);
		}
		uploader.id[data.uid][0].call(null, data,'flash');
	}
	uploader.uploadIoError = function(data) {}
	uploader.fileTooMuch = function(data){
		alert("选的图片太多了，我忙不过来呀");
	}
	setjwidth = function(jwidth){
		//hapj.page.setCookie('jwidth',jwidth,,'/');
		//console.log(jwidth);
	}
}();
var checkflashplayer = function(){
	var f = "", n = navigator;
	if (n.plugins && n.plugins.length) {
		for (var ii = 0; ii < n.plugins.length; ii++) {
			if (n.plugins[ii].name.indexOf('Shockwave Flash') != -1) {
				f = n.plugins[ii].description.split('Shockwave Flash ')[1];
				break;
			}
		}
	}else {
		if (window.ActiveXObject) {
			for (var ii = 10; ii >= 2; ii--) {
				try {
					var fl = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + ii + "');");
					if (fl) {
						f = ii + '.0';
						break;
					}
				} 
				catch (e) {
				}
			}
		}
	}
	return f;
		
}
var rgb2hex = function (rgb) {
	// nnd, Firefox / IE not the same, fxck
	if (rgb.charAt(0) == '#') {
		var aNum = rgb.replace(/#/, "").split("");
		if (aNum.length === 6) {
			return rgb;
		} else if (aNum.length === 3) {
			var numHex = "#";
			for ( var i = 0; i < aNum.length; i += 1) {
				numHex += (aNum[i] + aNum[i]);
			}
			return numHex;
		}

	} else if (/^(rgb|RGB)/.test(rgb)) {
		var aColor = rgb.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
		var strHex = "#";
		for ( var i = 0; i < aColor.length; i++) {
			var hex = Number(aColor[i]).toString(16);
			if (hex === "0") {
				hex += hex;
			}
			strHex += hex;
		}
		if (strHex.length !== 7) {
			strHex = rgb;
		}
		return strHex;
	}else{
		return rgb;
	}
}
var attrstyle = function (elem,attr){
	 if(elem.style[attr]){
		  // 若样式存在于html中,优先获取
		  return elem.style[attr];
	}else if(elem.currentStyle){
		  // ie下获取css教程属性最终样式(同于css优先级)
		  return elem.currentStyle[attr];
	}else if(document.defaultView && document.defaultView.getComputedStyle){
		  // w3c标准方法获取css属性最终样式(同于css优先级)
		  // 注意,此法属性原格式(text-align)获取的,故要转换一下
		  attr=attr.replace(/([A-Z])/g,'-$1').toLowerCase();
		  // 获取样式对象并获取属性值
		  return document.defaultView.getComputedStyle(elem,null).getPropertyValue(attr);
	 }else{
		  return null;
	}
}
var normalupload = function(style,uid,id,comConfig,rules,watermark){
var parms = rules?'?rules='+rules:'';
	parms += watermark?((parms)?'&':'?')+'watermark=1':'';
	var getTop = function(elem){
		var top = elem.offsetTop,parentElem = elem.offsetParent;
		while(parentElem != null){
			top += parentElem.offsetTop;
			parentElem = parentElem.offsetParent;
		}
		 if (document.compatMode == "BackCompat"){
			var docscrollTop = document.body.scrollTop; 
		}else{
			var docscrollTop = document.documentElement.scrollTop |document.body.scrollTop;
		};
		return top-docscrollTop;
	};
	var getLeft = function(elem){
		var left = elem.offsetLeft,parentElem = elem.offsetParent;
		while(parentElem != null){
			left += parentElem.offsetLeft;
			parentElem = parentElem.offsetParent;
		}
		 if (document.compatMode == "BackCompat"){
			var docscrollLeft = document.body.scrollLeft; 
		}else{
			var docscrollLeft = document.documentElement.scrollLeft |document.body.scrollLeft;
		};
		return left-docscrollLeft;
	};
	var w = (style.w)?'width:'+style.w+'px;':'',h = style.h?'height:'+style.h+'px;':'';
	var H = hapj,
		idElem = H.ui._id(id),
		html = '<form id="form'+uid+'" method="post" style="position:absolute;right:0;top:0;filter:alpha(opacity=0); " name="form'+uid+'" target="iframe'+uid+'" enctype="multipart/form-data" action="'+comConfig.upload_url+parms+'" >\
					<input type="file" name="upload" id="file'+uid+'" value="" style="'+w+h+'opacity:0;cursor:pointer;filter:alpha(opacity=0); "/> </form>',
		iframe = '<iframe scrolling="auto" id="iframe_data'+uid+'" frameborder="no" marginheight="0" style="display:none;" name="iframe'+uid+'"></iframe>';
				
	if(style.url){
		idElem.innerHTML = '<img src="'+style.url+'" style="width:'+style.w+'px;height:'+style.h+'px" />';
	}
	H.ui(idElem).css({position:'relative',overflow:'hidden'});
	H.ui(idElem).append(html);
	H.ui(document.body).append(iframe);
	
	H.ui._id('file'+uid).onchange = function(e){
		var val = this.value,
			imgName = val.substring(val.lastIndexOf('.')+1,val.length),
		type = val.substring(val.lastIndexOf('.')+1,val.length);
		type = type.toLowerCase();
		if(type!='jpg'&&type!='jpeg'&&type!='gif'&&type!='png'){
			alert('图片格式不对，请重新选择！');
			this.value = '';
		}else{
			this.form.submit();
		}
	}
}
/*
 * ! SWFObject v2.2 <http://code.google.com/p/swfobject/> is released under the
 * MIT License <http://www.opensource.org/licenses/mit-license.php>
 */

var swfobject = function() {
	
	var UNDEF = "undefined",
		OBJECT = "object",
		SHOCKWAVE_FLASH = "Shockwave Flash",
		SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
		FLASH_MIME_TYPE = "application/x-shockwave-flash",
		EXPRESS_INSTALL_ID = "SWFObjectExprInst",
		ON_READY_STATE_CHANGE = "onreadystatechange",
		
		win = window,
		doc = document,
		nav = navigator,
		
		plugin = false,
		domLoadFnArr = [main],
		regObjArr = [],
		objIdArr = [],
		listenersArr = [],
		storedAltContent,
		storedAltContentId,
		storedCallbackFn,
		storedCallbackObj,
		isDomLoaded = false,
		isExpressInstallActive = false,
		dynamicStylesheet,
		dynamicStylesheetMedia,
		autoHideShow = true,
	
	/*
	 * Centralized function for browser feature detection - User agent string
	 * detection is only used when no good alternative is possible - Is executed
	 * directly for optimal performance
	 */	
	ua = function() {
		var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
			u = nav.userAgent.toLowerCase(),
			p = nav.platform.toLowerCase(),
			windows = p ? /win/.test(p) : /win/.test(u),
			mac = p ? /mac/.test(p) : /mac/.test(u),
			webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns
																											// either
																											// the
																											// webkit
																											// version
																											// or
																											// false
																											// if
																											// not
																											// webkit
			ie = !+"\v1", // feature detection based on Andrea Giammarchi's
							// solution:
							// http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
			playerVersion = [0,0,0],
			d = null;
		if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
			d = nav.plugins[SHOCKWAVE_FLASH].description;
			if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin
																																			// indicates
																																			// whether
																																			// plug-ins
																																			// are
																																			// enabled
																																			// or
																																			// disabled
																																			// in
																																			// Safari
																																			// 3+
				plugin = true;
				ie = false; // cascaded feature detection for Internet Explorer
				d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
				playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
				playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
				playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
			}
		}
		else if (typeof win.ActiveXObject != UNDEF) {
			try {
				var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
				if (a) { // a will return null when ActiveX is disabled
					d = a.GetVariable("$version");
					if (d) {
						ie = true; // cascaded feature detection for Internet
									// Explorer
						d = d.split(" ")[1].split(",");
						playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
					}
				}
			}
			catch(e) {}
		}
		return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
	}(),
	
	/*
	 * Cross-browser onDomLoad - Will fire an event as soon as the DOM of a web
	 * page is loaded - Internet Explorer workaround based on Diego Perini's
	 * solution: http://javascript.nwbox.com/IEContentLoaded/ - Regular onload
	 * serves as fallback
	 */ 
	onDomLoad = function() {
		if (!ua.w3) { return; }
		if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function
																																											// is
																																											// fired
																																											// after
																																											// onload,
																																											// e.g.
																																											// when
																																											// script
																																											// is
																																											// inserted
																																											// dynamically
			callDomLoadFunctions();
		}
		if (!isDomLoaded) {
			if (typeof doc.addEventListener != UNDEF) {
				doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
			}		
			if (ua.ie && ua.win) {
				doc.attachEvent(ON_READY_STATE_CHANGE, function() {
					if (doc.readyState == "complete") {
						doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
						callDomLoadFunctions();
					}
				});
				if (win == top) { // if not inside an iframe
					(function(){
						if (isDomLoaded) { return; }
						try {
							doc.documentElement.doScroll("left");
						}
						catch(e) {
							setTimeout(arguments.callee, 0);
							return;
						}
						callDomLoadFunctions();
					})();
				}
			}
			if (ua.wk) {
				(function(){
					if (isDomLoaded) { return; }
					if (!/loaded|complete/.test(doc.readyState)) {
						setTimeout(arguments.callee, 0);
						return;
					}
					callDomLoadFunctions();
				})();
			}
			addLoadEvent(callDomLoadFunctions);
		}
	}();
	
	function callDomLoadFunctions() {
		if (isDomLoaded) { return; }
		try { // test if we can really add/remove elements to/from the DOM; we
				// don't want to fire it too early
			var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
			t.parentNode.removeChild(t);
		}
		catch (e) { return; }
		isDomLoaded = true;
		var dl = domLoadFnArr.length;
		for (var i = 0; i < dl; i++) {
			domLoadFnArr[i]();
		}
	}
	
	function addDomLoadEvent(fn) {
		if (isDomLoaded) {
			fn();
		}
		else { 
			domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only
													// available in IE5.5+
		}
	}
	
	/*
	 * Cross-browser onload - Based on James Edwards' solution:
	 * http://brothercake.com/site/resources/scripts/onload/ - Will fire an
	 * event as soon as a web page including all of its assets are loaded
	 */
	function addLoadEvent(fn) {
		if (typeof win.addEventListener != UNDEF) {
			win.addEventListener("load", fn, false);
		}
		else if (typeof doc.addEventListener != UNDEF) {
			doc.addEventListener("load", fn, false);
		}
		else if (typeof win.attachEvent != UNDEF) {
			addListener(win, "onload", fn);
		}
		else if (typeof win.onload == "function") {
			var fnOld = win.onload;
			win.onload = function() {
				fnOld();
				fn();
			};
		}
		else {
			win.onload = fn;
		}
	}
	
	/*
	 * Main function - Will preferably execute onDomLoad, otherwise onload (as a
	 * fallback)
	 */
	function main() { 
		if (plugin) {
			testPlayerVersion();
		}
		else {
			matchVersions();
		}
	}
	
	/*
	 * Detect the Flash Player version for non-Internet Explorer browsers -
	 * Detecting the plug-in version via the object element is more precise than
	 * using the plugins collection item's description: a. Both release and
	 * build numbers can be detected b. Avoid wrong descriptions by corrupt
	 * installers provided by Adobe c. Avoid wrong descriptions by multiple
	 * Flash Player entries in the plugin Array, caused by incorrect browser
	 * imports - Disadvantage of this method is that it depends on the
	 * availability of the DOM, while the plugins collection is immediately
	 * available
	 */
	function testPlayerVersion() {
		var b = doc.getElementsByTagName("body")[0];
		var o = createElement(OBJECT);
		o.setAttribute("type", FLASH_MIME_TYPE);
		var t = b.appendChild(o);
		if (t) {
			var counter = 0;
			(function(){
				if (typeof t.GetVariable != UNDEF) {
					var d = t.GetVariable("$version");
					if (d) {
						d = d.split(" ")[1].split(",");
						ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
					}
				}
				else if (counter < 10) {
					counter++;
					setTimeout(arguments.callee, 10);
					return;
				}
				b.removeChild(o);
				t = null;
				matchVersions();
			})();
		}
		else {
			matchVersions();
		}
	}
	
	/*
	 * Perform Flash Player and SWF version matching; static publishing only
	 */
	function matchVersions() {
		var rl = regObjArr.length;
		if (rl > 0) {
			for (var i = 0; i < rl; i++) { // for each registered object
											// element
				var id = regObjArr[i].id;
				var cb = regObjArr[i].callbackFn;
				var cbObj = {success:false, id:id};
				if (ua.pv[0] > 0) {
					var obj = getElementById(id);
					if (obj) {
						if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash
																									// Player
																									// version
																									// >=
																									// published
																									// SWF
																									// version:
																									// Houston,
																									// we
																									// have
																									// a
																									// match!
							setVisibility(id, true);
							if (cb) {
								cbObj.success = true;
								cbObj.ref = getObjectById(id);
								cb(cbObj);
							}
						}
						else if (regObjArr[i].expressInstall && canExpressInstall()) { // show
																						// the
																						// Adobe
																						// Express
																						// Install
																						// dialog
																						// if
																						// set
																						// by
																						// the
																						// web
																						// page
																						// author
																						// and
																						// if
																						// supported
							var att = {};
							att.data = regObjArr[i].expressInstall;
							att.width = obj.getAttribute("width") || "0";
							att.height = obj.getAttribute("height") || "0";
							if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
							if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
							// parse HTML object param element's name-value
							// pairs
							var par = {};
							var p = obj.getElementsByTagName("param");
							var pl = p.length;
							for (var j = 0; j < pl; j++) {
								if (p[j].getAttribute("name").toLowerCase() != "movie") {
									par[p[j].getAttribute("name")] = p[j].getAttribute("value");
								}
							}
							showExpressInstall(att, par, id, cb);
						}
						else { // Flash Player and SWF version mismatch or an
								// older Webkit engine that ignores the HTML
								// object element's nested param elements:
								// display alternative content instead of SWF
							displayAltContent(obj);
							if (cb) { cb(cbObj); }
						}
					}
				}
				else {	// if no Flash Player is installed or the fp version
						// cannot be detected we let the HTML object element do
						// its job (either show a SWF or alternative content)
					setVisibility(id, true);
					if (cb) {
						var o = getObjectById(id); // test whether there is an
													// HTML object element or
													// not
						if (o && typeof o.SetVariable != UNDEF) { 
							cbObj.success = true;
							cbObj.ref = o;
						}
						cb(cbObj);
					}
				}
			}
		}
	}
	
	function getObjectById(objectIdStr) {
		var r = null;
		var o = getElementById(objectIdStr);
		if (o && o.nodeName == "OBJECT") {
			if (typeof o.SetVariable != UNDEF) {
				r = o;
			}
			else {
				var n = o.getElementsByTagName(OBJECT)[0];
				if (n) {
					r = n;
				}
			}
		}
		return r;
	}
	
	/*
	 * Requirements for Adobe Express Install - only one instance can be active
	 * at a time - fp 6.0.65 or higher - Win/Mac OS only - no Webkit engines
	 * older than version 312
	 */
	function canExpressInstall() {
		return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
	}
	
	/*
	 * Show the Adobe Express Install dialog - Reference:
	 * http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75
	 */
	function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
		isExpressInstallActive = true;
		storedCallbackFn = callbackFn || null;
		storedCallbackObj = {success:false, id:replaceElemIdStr};
		var obj = getElementById(replaceElemIdStr);
		if (obj) {
			if (obj.nodeName == "OBJECT") { // static publishing
				storedAltContent = abstractAltContent(obj);
				storedAltContentId = null;
			}
			else { // dynamic publishing
				storedAltContent = obj;
				storedAltContentId = replaceElemIdStr;
			}
			att.id = EXPRESS_INSTALL_ID;
			if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
			if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
			doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
			var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
				fv = "MMredirectURL=" + encodeURI(window.location).toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
			if (typeof par.flashvars != UNDEF) {
				par.flashvars += "&" + fv;
			}
			else {
				par.flashvars = fv;
			}
			// IE only: when a SWF is loading (AND: not available in cache) wait
			// for the readyState of the object element to become 4 before
			// removing it,
			// because you cannot properly cancel a loading SWF file without
			// breaking browser load references, also obj.onreadystatechange
			// doesn't work
			if (ua.ie && ua.win && obj.readyState != 4) {
				var newObj = createElement("div");
				replaceElemIdStr += "SWFObjectNew";
				newObj.setAttribute("id", replaceElemIdStr);
				obj.parentNode.insertBefore(newObj, obj); // insert
															// placeholder div
															// that will be
															// replaced by the
															// object element
															// that loads
															// expressinstall.swf
				obj.style.display = "none";
				(function(){
					if (obj.readyState == 4) {
						obj.parentNode.removeChild(obj);
					}
					else {
						setTimeout(arguments.callee, 10);
					}
				})();
			}
			createSWF(att, par, replaceElemIdStr);
		}
	}
	
	/*
	 * Functions to abstract and display alternative content
	 */
	function displayAltContent(obj) {
		if (ua.ie && ua.win && obj.readyState != 4) {
			// IE only: when a SWF is loading (AND: not available in cache) wait
			// for the readyState of the object element to become 4 before
			// removing it,
			// because you cannot properly cancel a loading SWF file without
			// breaking browser load references, also obj.onreadystatechange
			// doesn't work
			var el = createElement("div");
			obj.parentNode.insertBefore(el, obj); // insert placeholder div
													// that will be replaced by
													// the alternative content
			el.parentNode.replaceChild(abstractAltContent(obj), el);
			obj.style.display = "none";
			(function(){
				if (obj.readyState == 4) {
					obj.parentNode.removeChild(obj);
				}
				else {
					setTimeout(arguments.callee, 10);
				}
			})();
		}
		else {
			obj.parentNode.replaceChild(abstractAltContent(obj), obj);
		}
	} 

	function abstractAltContent(obj) {
		var ac = createElement("div");
		if (ua.win && ua.ie) {
			ac.innerHTML = obj.innerHTML;
		}
		else {
			var nestedObj = obj.getElementsByTagName(OBJECT)[0];
			if (nestedObj) {
				var c = nestedObj.childNodes;
				if (c) {
					var cl = c.length;
					for (var i = 0; i < cl; i++) {
						if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
							ac.appendChild(c[i].cloneNode(true));
						}
					}
				}
			}
		}
		return ac;
	}
	
	/*
	 * Cross-browser dynamic SWF creation
	 */
	function createSWF(attObj, parObj, id) {
		var r, el = getElementById(id);
		if (ua.wk && ua.wk < 312) { return r; }
		if (el) {
			if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the
												// object element, it will
												// inherit the 'id' from the
												// alternative content
				attObj.id = id;
			}
			if (ua.ie && ua.win) { // Internet Explorer + the HTML object
									// element + W3C DOM methods do not combine:
									// fall back to outerHTML
				var att = "";
				for (var i in attObj) {
					if (attObj[i] != Object.prototype[i]) { // filter out
															// prototype
															// additions from
															// other potential
															// libraries
						if (i.toLowerCase() == "data") {
							parObj.movie = attObj[i];
						}
						else if (i.toLowerCase() == "styleclass") { // 'class'
																	// is an
																	// ECMA4
																	// reserved
																	// keyword
							att += ' class="' + attObj[i] + '"';
						}
						else if (i.toLowerCase() != "classid") {
							att += ' ' + i + '="' + attObj[i] + '"';
						}
					}
				}
				var par = "";
				for (var j in parObj) {
					if (parObj[j] != Object.prototype[j]) { // filter out
															// prototype
															// additions from
															// other potential
															// libraries
						par += '<param name="' + j + '" value="' + parObj[j] + '" />';
					}
				}
				el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
				objIdArr[objIdArr.length] = attObj.id; // stored to fix object
														// 'leaks' on unload
														// (dynamic publishing
														// only)
				r = getElementById(attObj.id);	
			}
			else { // well-behaving browsers
				var o = createElement(OBJECT);
				o.setAttribute("type", FLASH_MIME_TYPE);
				for (var m in attObj) {
					if (attObj[m] != Object.prototype[m]) { // filter out
															// prototype
															// additions from
															// other potential
															// libraries
						if (m.toLowerCase() == "styleclass") { // 'class' is an
																// ECMA4
																// reserved
																// keyword
							o.setAttribute("class", attObj[m]);
						}
						else if (m.toLowerCase() != "classid") { // filter
																	// out IE
																	// specific
																	// attribute
							o.setAttribute(m, attObj[m]);
						}
					}
				}
				for (var n in parObj) {
					if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter
																							// out
																							// prototype
																							// additions
																							// from
																							// other
																							// potential
																							// libraries
																							// and
																							// IE
																							// specific
																							// param
																							// element
						createObjParam(o, n, parObj[n]);
					}
				}
				el.parentNode.replaceChild(o, el);
				r = o;
			}
		}
		return r;
	}
	
	function createObjParam(el, pName, pValue) {
		var p = createElement("param");
		p.setAttribute("name", pName);	
		p.setAttribute("value", pValue);
		el.appendChild(p);
	}
	
	/*
	 * Cross-browser SWF removal - Especially needed to safely and completely
	 * remove a SWF in Internet Explorer
	 */
	function removeSWF(id) {
		var obj = getElementById(id);
		if (obj && obj.nodeName == "OBJECT") {
			if (ua.ie && ua.win) {
				obj.style.display = "none";
				(function(){
					if (obj.readyState == 4) {
						removeObjectInIE(id);
					}
					else {
						setTimeout(arguments.callee, 10);
					}
				})();
			}
			else {
				obj.parentNode.removeChild(obj);
			}
		}
	}
	
	function removeObjectInIE(id) {
		var obj = getElementById(id);
		if (obj) {
			for (var i in obj) {
				if (typeof obj[i] == "function") {
					obj[i] = null;
				}
			}
			obj.parentNode.removeChild(obj);
		}
	}
	
	/*
	 * Functions to optimize JavaScript compression
	 */
	function getElementById(id) {
		var el = null;
		try {
			el = doc.getElementById(id);
		}
		catch (e) {}
		return el;
	}
	
	function createElement(el) {
		return doc.createElement(el);
	}
	
	/*
	 * Updated attachEvent function for Internet Explorer - Stores attachEvent
	 * information in an Array, so on unload the detachEvent functions can be
	 * called to avoid memory leaks
	 */	
	function addListener(target, eventType, fn) {
		target.attachEvent(eventType, fn);
		listenersArr[listenersArr.length] = [target, eventType, fn];
	}
	
	/*
	 * Flash Player and SWF content version matching
	 */
	function hasPlayerVersion(rv) {
		var pv = ua.pv, v = rv.split(".");
		v[0] = parseInt(v[0], 10);
		v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9"
										// instead of "9.0.0"
		v[2] = parseInt(v[2], 10) || 0;
		return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
	}
	
	/*
	 * Cross-browser dynamic CSS creation - Based on Bobby van der Sluis'
	 * solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php
	 */	
	function createCSS(sel, decl, media, newStyle) {
		if (ua.ie && ua.mac) { return; }
		var h = doc.getElementsByTagName("head")[0];
		if (!h) { return; } // to also support badly authored HTML pages that
							// lack a head element
		var m = (media && typeof media == "string") ? media : "screen";
		if (newStyle) {
			dynamicStylesheet = null;
			dynamicStylesheetMedia = null;
		}
		if (!dynamicStylesheet || dynamicStylesheetMedia != m) { 
			// create dynamic stylesheet + get a global reference to it
			var s = createElement("style");
			s.setAttribute("type", "text/css");
			s.setAttribute("media", m);
			dynamicStylesheet = h.appendChild(s);
			if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
				dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
			}
			dynamicStylesheetMedia = m;
		}
		// add style rule
		if (ua.ie && ua.win) {
			if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
				dynamicStylesheet.addRule(sel, decl);
			}
		}
		else {
			if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
				dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
			}
		}
	}
	
	function setVisibility(id, isVisible) {
		if (!autoHideShow) { return; }
		var v = isVisible ? "visible" : "hidden";
		if (isDomLoaded && getElementById(id)) {
			getElementById(id).style.visibility = v;
		}
		else {
			createCSS("#" + id, "visibility:" + v);
		}
	}

	/*
	 * Filter to avoid XSS attacks
	 */
	function urlEncodeIfNecessary(s) {
		var regex = /[\\\"<>\.;]/;
		var hasBadChars = regex.exec(s) != null;
		return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
	}
	
	/*
	 * Release memory to avoid memory leaks caused by closures, fix hanging
	 * audio/video threads and force open sockets/NetConnections to disconnect
	 * (Internet Explorer only)
	 */
	var cleanup = function() {
		if (ua.ie && ua.win) {
			window.attachEvent("onunload", function() {
				// remove listeners to avoid memory leaks
				var ll = listenersArr.length;
				for (var i = 0; i < ll; i++) {
					listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
				}
				// cleanup dynamically embedded objects to fix audio/video
				// threads and force open sockets and NetConnections to
				// disconnect
				var il = objIdArr.length;
				for (var j = 0; j < il; j++) {
					removeSWF(objIdArr[j]);
				}
				// cleanup library's main closures to avoid memory leaks
				for (var k in ua) {
					ua[k] = null;
				}
				ua = null;
				for (var l in swfobject) {
					swfobject[l] = null;
				}
				swfobject = null;
			});
		}
	}();
	
	return {
		/*
		 * Public API - Reference:
		 * http://code.google.com/p/swfobject/wiki/documentation
		 */ 
		registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
			if (ua.w3 && objectIdStr && swfVersionStr) {
				var regObj = {};
				regObj.id = objectIdStr;
				regObj.swfVersion = swfVersionStr;
				regObj.expressInstall = xiSwfUrlStr;
				regObj.callbackFn = callbackFn;
				regObjArr[regObjArr.length] = regObj;
				setVisibility(objectIdStr, false);
			}
			else if (callbackFn) {
				callbackFn({success:false, id:objectIdStr});
			}
		},
		
		getObjectById: function(objectIdStr) {
			if (ua.w3) {
				return getObjectById(objectIdStr);
			}
		},
		
		embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
			var callbackObj = {success:false, id:replaceElemIdStr};
			if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
				setVisibility(replaceElemIdStr, false);
				addDomLoadEvent(function() {
					widthStr += ""; // auto-convert to string
					heightStr += "";
					var att = {};
					if (attObj && typeof attObj === OBJECT) {
						for (var i in attObj) { // copy object to avoid the use
												// of references, because web
												// authors often reuse attObj
												// for multiple SWFs
							att[i] = attObj[i];
						}
					}
					att.data = swfUrlStr;
					att.width = widthStr;
					att.height = heightStr;
					var par = {}; 
					if (parObj && typeof parObj === OBJECT) {
						for (var j in parObj) { // copy object to avoid the use
												// of references, because web
												// authors often reuse parObj
												// for multiple SWFs
							par[j] = parObj[j];
						}
					}
					if (flashvarsObj && typeof flashvarsObj === OBJECT) {
						for (var k in flashvarsObj) { // copy object to avoid
														// the use of
														// references, because
														// web authors often
														// reuse flashvarsObj
														// for multiple SWFs
							if (typeof par.flashvars != UNDEF) {
								par.flashvars += "&" + k + "=" + flashvarsObj[k];
							}
							else {
								par.flashvars = k + "=" + flashvarsObj[k];
							}
						}
					}
					if (hasPlayerVersion(swfVersionStr)) { // create SWF
						var obj = createSWF(att, par, replaceElemIdStr);
						if (att.id == replaceElemIdStr) {
							setVisibility(replaceElemIdStr, true);
						}
						callbackObj.success = true;
						callbackObj.ref = obj;
					}
					else if (xiSwfUrlStr && canExpressInstall()) { // show
																	// Adobe
																	// Express
																	// Install
						att.data = xiSwfUrlStr;
						showExpressInstall(att, par, replaceElemIdStr, callbackFn);
						return;
					}
					else { // show alternative content
						setVisibility(replaceElemIdStr, true);
					}
					if (callbackFn) { callbackFn(callbackObj); }
				});
			}
			else if (callbackFn) { callbackFn(callbackObj);	}
		},
		
		switchOffAutoHideShow: function() {
			autoHideShow = false;
		},
		
		ua: ua,
		
		getFlashPlayerVersion: function() {
			return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
		},
		
		hasFlashPlayerVersion: hasPlayerVersion,
		
		createSWF: function(attObj, parObj, replaceElemIdStr) {
			if (ua.w3) {
				return createSWF(attObj, parObj, replaceElemIdStr);
			}
			else {
				return undefined;
			}
		},
		
		showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
			if (ua.w3 && canExpressInstall()) {
				showExpressInstall(att, par, replaceElemIdStr, callbackFn);
			}
		},
		
		removeSWF: function(objElemIdStr) {
			if (ua.w3) {
				removeSWF(objElemIdStr);
			}
		},
		
		createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
			if (ua.w3) {
				createCSS(selStr, declStr, mediaStr, newStyleBoolean);
			}
		},
		
		addDomLoadEvent: addDomLoadEvent,
		
		addLoadEvent: addLoadEvent,
		
		getQueryParamValue: function(param) {
			var q = doc.location.search || doc.location.hash;
			if (q) {
				if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question
															// mark
				if (param == null) {
					return urlEncodeIfNecessary(q);
				}
				var pairs = q.split("&");
				for (var i = 0; i < pairs.length; i++) {
					if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
						return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
					}
				}
			}
			return "";
		},
		
		// For internal usage only
		expressInstallCallback: function() {
			if (isExpressInstallActive) {
				var obj = getElementById(EXPRESS_INSTALL_ID);
				if (obj && storedAltContent) {
					obj.parentNode.replaceChild(storedAltContent, obj);
					if (storedAltContentId) {
						setVisibility(storedAltContentId, true);
						if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
					}
					if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
				}
				isExpressInstallActive = false;
			} 
		}
	};
}();


/*
 * ! MultiUpload for xheditor @requires xhEditor
 * 
 * @author Yanis.Wang<yanis.wang@gmail.com> @site http://xheditor.com/ @licence
 * LGPL(http://www.opensource.org/licenses/lgpl-license.php)
 * 
 * @Version: 0.9.2 (build 100505)
 */
var swfu,selQueue=[],selectID,arrMsg=[],allSize=0,uploadSize=0;
function removeFile()
{
	var file;
	if(!selectID)return;
	for(var i in selQueue)
	{
		file=selQueue[i];
		if(file.id==selectID)
		{
			selQueue.splice(i,1);
			allSize-=file.size;
			swfu.cancelUpload(file.id);
			$('#'+file.id).remove();
			selectID=null;
			break;
		}
	}
	$('#btnClear').hide();
	if(selQueue.length==0)$('#controlBtns').hide();
}
function startUploadFiles()
{
	if (swfu.getStats().files_queued > 0) {
		$('#controlBtns').hide();
		swfu.startUpload();
	} else {
		Handler.alert('上传前请先添加文件');
	}
}
function setFileState(fileid,txt)
{
	$('#'+fileid+'_state').text(txt);
}
function fileQueued(file)// 队列添加成功
{
	for(var i in selQueue)if(selQueue[i].name==file.name){swfu.cancelUpload(file.id);return false;}// 防止同名文件重复添加
	if(selQueue.length==0)$('#controlBtns').show();
	selQueue.push(file);
	allSize+=file.size;
	$('#listBody').append('<tr id="'+file.id+'"><td>'+file.name+'</td><td>'+formatBytes(file.size)+'</td><td id="'+file.id+'_state">就绪</td></tr>');
	$('#'+file.id).hover(function(){$(this).addClass('hover');},function(){$(this).removeClass('hover');})
	.click(function(){selectID=file.id;$('#listBody tr').removeClass('select');$(this).removeClass('hover').addClass('select');$('#btnClear').show();})
}
function fileQueueError(file, errorCode, message)// 队列添加失败
{
	var errorName='';
	switch (errorCode)
	{
		case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
			errorName = "只能同时上传 "+this.settings.file_upload_limit+" 个文件";
			break;
		case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
			errorName = "选择的文件超过了当前大小限制："+this.settings.file_size_limit;
			break;
		case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
			errorName = "零大小文件";
			break;
		case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
			errorName = "文件扩展名必需为："+this.settings.file_types_description+" ("+this.settings.file_types+")";
			break;
		default:
			errorName = "未知错误";
			break;
	}
	Handler.alert(errorName);
}
function uploadStart(file)// 单文件上传开始
{
	setFileState(file.id,'上传中…');
}
function uploadProgress(file, bytesLoaded, bytesTotal)// 单文件上传进度
{
	var percent=Math.ceil((uploadSize+bytesLoaded)/allSize*100);
	$('#progressBar span').text(percent+'% ('+formatBytes(uploadSize+bytesLoaded)+' / '+formatBytes(allSize)+')');
	$('#progressBar div').css('width',percent+'%');
}
function uploadSuccess(file, serverData)// 单文件上传成功
{
	var data=Object;
	try{eval("data=" + serverData);}catch(ex){};
	if(data.err)
	{
		if('hapn.ok' == data.err)
		{
			uploadSize+=file.size;
			arrMsg.push(data.data);
			setFileState(file.id,'上传成功');
		}
		else
		{
			setFileState(file.id,'上传失败');
			Handler.alert(data.err);
		}
	}
	else setFileState(file.id,'上传失败！');
}
function uploadError(file, errorCode, message)// 单文件上传错误
{
	setFileState(file.id,'上传失败！');
}
function uploadComplete(file)// 文件上传周期结束
{
	if (swfu.getStats().files_queued > 0) {
		swfu.startUpload();
	} else {
		if (arrMsg && arrMsg.length > 1) {
			for(var i = 0, l = arrMsg.length; i < l; i++) {
				var row = arrMsg[i];
				if (row.url && row.url.substr(0) != '!') {
					row.url = '!' + row.url;
				}
			}
		}
		uploadAllComplete();
	}
}
function uploadAllComplete()// 全部文件上传成功
{
	callback(arrMsg);
}
function formatBytes(bytes) {
	var s = ['Byte', 'KB', 'MB', 'GB', 'TB', 'PB'];
	var e = Math.floor(Math.log(bytes)/Math.log(1024));
	return (bytes/Math.pow(1024, Math.floor(e))).toFixed(2)+" "+s[e];
}
